﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Diagnostics;
//using Mbs.Modularity.AddIns;
//using Mbs.Services;
//using System.IO;
//using System.Reflection;
//using Mbs.Log;

//namespace Mbs.Modularity
//{
//    public class ModuleManager:MarshalByRefObject, IModuleManager
//    {
//        public IModuleRepository ModuleRepository { get; set; }
//        public IModuleMetaEnumerator ModuleMetaEnumerator { get; set; }

//        private static readonly ILog log = LoggerManager.GetLogger(typeof(ModuleManager));

//        public ModuleManager()
//        {
//            Initialize();
//        }

//        private void Initialize()
//        {
//            DefaultDomain = true;
//            const string defaultConfig = @"AddIns\Mbs.AddIn";

//            log.Info("begin initialize......");

//            if (File.Exists(defaultConfig))
//            {
//                log.Info("begin load system addin for mbs.addin file......");
//                var addin = AddIn.Get(defaultConfig);
//                log.Info("end load system addin for mbs.addin file......");

//                if (addin != null && addin.Enabled)
//                {
//                    AddInTree.Instance.Install(addin);
//                    if (addin.Runtime.Imports.Count > 0)
//                        foreach (var item in addin.Runtime.Imports)
//                            Assembly.LoadFrom(item);
//                    if (addin.Runtime.Services != null)
//                        ServiceLocator.Root.Initialize(addin.Runtime.Services, ServiceLocator.ClassLoader);
//                }
//            }

//            log.Info("end initialize......");
//        }

//        private IClassLoader CreateClassLoader()
//        {
//            if (DefaultDomain)
//                return ServiceLocator.ClassLoader;
//            return new RemoteClassLoader();
//        }

//        public bool DefaultDomain { get; set; }

//        public void Start()
//        {
//            Debug.Assert(ModuleRepository != null);

//            log.Debug("begin start modules......");

//            var items = ModuleRepository.GetModules();
//            if (items != null && items.Length > 0)
//                foreach (var item in items)
//                    if (!item.Meta.LazyLoad)
//                    {
//                        Action startHandler = item.Start;
//                        item.ClassLoader.Invoke(startHandler);
//                    }

//            log.Debug("end start modules......");
//        }

//        public void Install()
//        {
//            Debug.Assert(ModuleMetaEnumerator != null);

//            log.Debug("begin install modules......");

//            var moduleMetas = ModuleMetaEnumerator.GetModules();
//            if (moduleMetas != null && moduleMetas.Length > 0)
//                foreach (var meta in moduleMetas)
//                    InstallModule(meta);

//            log.Debug("end install modules......");
//        }

//        public void Stop()
//        {
//            Debug.Assert(ModuleRepository != null);

//            var items = ModuleRepository.GetModules().Reverse().ToArray();
//            Array.ForEach<IModule>(items, (item) => item.Stop());
//        }

//        public void Shutdown()
//        {
//            Debug.Assert(ModuleRepository != null);

//            var items = ModuleRepository.GetModules().Reverse().ToArray();
//            Array.ForEach<IModule>(items, item =>
//            {
//                int id = item.First;

//                Action stopHandler = item.Stop;
//                item.ClassLoader.Invoke(stopHandler);

//                ModuleRepository.Unregister(item);
//                if (item.Meta.AddIn != null && item.Meta.AddIn.Enabled)
//                    AddInTree.Instance.Uninstall(item.Meta.AddIn);
//                item = null;
//            });
//        }

//        public IModule InstallModule(IModuleMeta info)
//        {
//            var classLoader = CreateClassLoader();
//            var module = classLoader.NewInstance<Module>(ModuleRepository.Count + 1, info,ServiceLocator.MessageRouter, ServiceLocator.ElementService);
//            module.ClassLoader = classLoader;

//            CheckInstallBundle(module);
//            InstallModuleInternal(module);

//            if (info.AddIn != null && info.AddIn.Enabled)
//                AddInTree.Instance.Install(info.AddIn);
//            return module;
//        }

//        public IModule InstallModule(string moduleFile)
//        {
//            Debug.Assert(ModuleRepository != null);
//            Debug.Assert(string.IsNullOrEmpty(moduleFile),"moduleFile == null" );

//            var meta = ModuleMetaEnumerator.Do(moduleFile, false);
//            return InstallModule(meta);
//        }


//        private void CheckInstallBundle(Module module)
//        {
//            IModule item = ModuleRepository.GetModule(module.Meta.Id, module.Meta.Version);
//            if (item != null)
//                throw new ModuleException("Module is already installed.");
//        }

//        private IModule InstallModuleInternal(Module module)
//        {
//            ModuleRepository.Do(module);

//            if (module.State == ModuleState.Installed)
//            {
//                ServiceLocator.MessageRouter.Publish(this, new ModuleEventArgs(
//                        ModuleTransition.Installed, module));
//            }

//            return module;
//        }

//        public void UninstallModule(int id)
//        {
//            Debug.Assert(ModuleRepository != null);

//            try
//            {
//                IModule module = ModuleRepository.GetModule(id);
//                ModuleRepository.Unregister(module);
//            }
//            catch (Exception ex)
//            {
//                var newEx = new ModuleException("Uninstall module threw a exception.", ex);
//                log.Error(newEx.Message, newEx);
//                newEx.RaiseException();
//            }
//        }

//        public IModule StartModule(int id)
//        {
//            Debug.Assert(ModuleRepository != null);

//            try
//            {
//                IModule module = ModuleRepository.GetModule(id);

//                if (module == null)
//                    throw new ModuleException(String.Format("Module not found.Module First:{0}", id));
//                if (module.State != ModuleState.Installed)
//                    throw new ModuleException("Module is aready started.");

//                module.Start();
//                return module;
//            }
//            catch (Exception ex)
//            {
//                log.Error(ex.Message, ex);
//                return null;
//            }
//        }

//        public void StopModule(int id)
//        {
//            Debug.Assert(ModuleRepository != null);

//            try
//            {
//                IModule module = ModuleRepository.GetModule(id);
//                if (module == null)
//                    throw new ModuleException(String.Format("Module not found.Module First:{0}", id));
//                if (module.State != ModuleState.Active)
//                    throw new ModuleException("Module is not active.");

//                module.Stop();
//            }
//            catch (Exception ex)
//            {
//                ex.RaiseException();
//            }
//        }

//        public void StartModule(IModule module)
//        {
//            if (module != null)
//                module.Start();
//        }

//        public void Dispose()
//        {
//            Shutdown();
//        }

//    }
//}
